﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Pout_Porri.Objects.Interface;
using Pout_Porri.Utils;
using System.IO;

namespace Pout_Porri.Objects
{
    public enum LinkStates
    {
        running,
        crouching,
        stand,
        jumping,
        falling,
        attacking,
        dying,
    }

    class Link : PhysicsGameEntity, IGameEntity
    {
        protected LinkStates currentState;

        private float jumpHeight = 15;

        int startMapHalfScreen;
        int endMapHalfScreen;

        private Sword sword;

        public Link(Texture2D image, Vector2 position, Vector2 velocity, Texture2D swordImg)
            : base(image, position, velocity, true)
        {
            this.texture = image;
            this.spriteTexture = new Texture2D(Game1.graphics.GraphicsDevice, 61, 80);
            DefaultVelocityX = velocity.X;
            this.currentState = LinkStates.stand;
            this.configAnimations();

            startMapHalfScreen = Utils.GameConfig.GAME_WIDTH / 2;
            endMapHalfScreen = ((Utils.GameConfig.COLS * Utils.GameConfig.TILE_SIZE) - (Utils.GameConfig.GAME_WIDTH / 2));

            sword = new Sword(swordImg, new Vector2(200, 400), new Vector2(3, 1));
            sword.Mass = 1f;
            sword.AccelerationX = 0.02f;
            sword.MaxVelocityX = 5;
        }

        public void configAnimations()
        {
            Animation linkStand = new Animation("stand", new Vector2(61, 80), 100, 6, 0, 1, Axis.X);
            Animation linkRunning = new Animation("running", new Vector2(61, 80), 80, 0, 0, 6, Axis.X);
            Animation linkJumping = new Animation("jumping", new Vector2(61, 80), 250, 0, 1, 3, Axis.X);
            Animation linkFalling = new Animation("falling", new Vector2(61, 80), 250, 3, 1, 3, Axis.X);
            Animation linkCrouching = new Animation("crouching", new Vector2(61, 80), 250, 7, 0, 1, Axis.X);
            Animation linkAttacking = new Animation("attacking", new Vector2(61, 80), 75, 0, 2, 4, Axis.X);
            Animation linkDying = new Animation("dying", new Vector2(61, 80), 250, 8, 0, 2, Axis.X);

            this.addAnimation(linkStand);
            this.addAnimation(linkRunning);
            this.addAnimation(linkJumping);
            this.addAnimation(linkFalling);
            this.addAnimation(linkCrouching);
            this.addAnimation(linkAttacking);
            this.addAnimation(linkDying);

            this.setCurrentAnimation("stand");
        }

        public void handleInput(GameTime gameTime)
        {
            LinkStates pState = currentState;

            direction.X = 0;

            if (IsGrounded() && currentState != LinkStates.attacking)
                pState = LinkStates.stand;

            //if (currentState != LinkStates.jumping && currentState != LinkStates.falling && !isClimbingUp && !isClimbingDown)
            //    pState = LinkStates.stand;

            if (currentState != LinkStates.attacking)
            {
                if (Game1.keyboardState.IsKeyDown(Keys.Right))
                {
                    this.deFlipHorizontally();
                    sword.deFlipHorizontally();

                    if (currentState != LinkStates.crouching)
                    {
                        direction.X = 1;
                        if (currentState != LinkStates.jumping && currentState != LinkStates.falling)
                        {
                            pState = LinkStates.running;
                        }
                    }
                }
                else if (Game1.keyboardState.IsKeyDown(Keys.Left))
                {
                    this.flipHorizontally();
                    sword.flipHorizontally();

                    if (currentState != LinkStates.crouching)
                    {
                        direction.X = -1;
                        if (currentState != LinkStates.jumping && currentState != LinkStates.falling)
                            pState = LinkStates.running;
                    }
                }
            

                // pulo
                if (Game1.keyboardState.IsKeyDown(Keys.Space) && !Game1.previusKeyboardState.IsKeyDown(Keys.Space) && IsGrounded())
                {
                    this.Velocity = new Vector2(this.Velocity.X, -jumpHeight);
                    this.setGrounded(false);
                    pState = LinkStates.jumping;
                }

                // queda
                if (this.direction.Y > 0 && this.velocity.Y > 0 && !IsGrounded())
                    pState = LinkStates.falling;

                // agachar
                if (Game1.keyboardState.IsKeyDown(Keys.Down) && currentState != LinkStates.jumping
                    && currentState != LinkStates.falling && currentState != LinkStates.running)
                {
                    pState = LinkStates.crouching;
                    setGrounded(true);
                }

                // correr
                if (Game1.keyboardState.IsKeyDown(Keys.LeftShift) && this.direction.X != 0 && this.direction.Y == 0)
                    isRunning = true;

                if (Game1.keyboardState.IsKeyUp(Keys.LeftShift))
                    isRunning = false;

                // ataque
                if (Game1.keyboardState.IsKeyDown(Keys.LeftControl) && !Game1.previusKeyboardState.IsKeyDown(Keys.LeftControl))
                {
                    pState = LinkStates.attacking;
                }

                if (pState != currentState)
                {
                    currentState = pState;
                }
            }
        }

        public override void setGrounded(bool b)
        {
            base.setGrounded(b);
        }

        public void setSwordPosition()
        {
            sword.position.X = base.position.X - 45;
            sword.position.Y = base.position.Y;
        }

        public override void update(GameTime gameTime)
        {
            handleInput(gameTime);
            updateCamera();
            //currentAnimationRect = this.AnimationRect(this.getCurrentAnimation());

            this.applyMovement(gameTime);
            checkMatrixCollisionInY();

            #region "animation"

            if (currentState == LinkStates.stand)
            {
                this.setCurrentAnimation("stand");
                sword.setCurrentAnimation("idle");
            }
            else if (currentState == LinkStates.running)
            {
                this.setCurrentAnimation("running");
            }
            else if (currentState == LinkStates.jumping)
            {
                this.setCurrentAnimation("jumping");
            }
            else if (currentState == LinkStates.falling)
            {
                this.setCurrentAnimation("falling");
            }
            else if (currentState == LinkStates.crouching)
            {
                this.setCurrentAnimation("crouching");
            }
            else if (currentState == LinkStates.attacking)
            {
                if (getCurrentAnimation() != searchAnimation("attacking"))
                    this.setCurrentAnimation("attacking");
                    sword.setCurrentAnimation("attacking");
            }
            else if (currentState == LinkStates.dying)
            {
                Game1.window.Title = "dying";
                this.setCurrentAnimation("dying");
            }

            if (this.isAnimationFinished() && currentState == LinkStates.attacking)
                currentState = LinkStates.stand;

            #endregion

            setSwordPosition();

            sword.update(gameTime);
            base.update(gameTime);
        }

        private void updateCamera()
        {
            Vector2 playerCamera;

            if (position.X <= startMapHalfScreen)
                playerCamera = new Vector2(startMapHalfScreen, 288);
            else if (position.X > startMapHalfScreen && position.X < endMapHalfScreen)
                playerCamera = new Vector2(this.position.X, 288);
            else
                playerCamera = new Vector2(endMapHalfScreen, 288);

            Game1.camera.Update(playerCamera - Game1.camera.Position);
        }

        public override void draw(SpriteBatch spriteBatch)
        {
            base.draw(spriteBatch);
            sword.draw(spriteBatch);

            // desenhando a animação da espada
            //if (currentState == LinkStates.attacking)
            //{

            //    if (base.prevFrame.X == 2)
            //    {
            //        Rectangle srcRect = new Rectangle(246, 186, 147, 23);
            //        Rectangle dstRect = new Rectangle(CollisionRect.X - 37, CollisionRect.Y + 26, 147, 23);
            //        spriteBatch.Draw(getImage(), dstRect, srcRect, Color.White);
            //    }
            //    else if (base.prevFrame.X == 3)
            //    {
            //        Rectangle srcRect = new Rectangle(396, 194, 44, 15);
            //        Rectangle dstRect = new Rectangle(CollisionRect.X - 38, CollisionRect.Y + 34, 44, 15);
            //        spriteBatch.Draw(getImage(), dstRect, srcRect, Color.White);
            //    }
            //}
        }
    }
}
